package study.Day_3;

/**
 * @Classname: Day_three
 * @Description: 描述
 * @Date: 2021/9/15
 * @Author: huwei
 */

/**
 * 给定一个字符串s请你找出其中不含有重复字符的最长子串的长度。
 */

/**
 * 示例 1:
 * 输入: s = "abcabcbb"
 * 输出: 3
 * 解释: 因为无重复字符的最长子串是 "abc"，所以其长度为 3。
 *
 * 示例 2:
 * 输入: s = "bbbbb"
 * 输出: 1
 * 解释: 因为无重复字符的最长子串是 "b"，所以其长度为 1。
 *
 * 实例3:
 * 输入: s = "pwwkew"
 * 输出: 3
 * 解释: 因为无重复字符的最长子串是"wke"，所以其长度为 3。
 *      请注意，你的答案必须是 子串 的长度，"pwke"是一个子序列，不是子串。
 *
 * 示例 4:
 * 输入: s = ""
 * 输出: 0
 */
public class Day_three {
    public Integer lengthOfLongSubstring(String s) {
        // 使用ASCAII帮助进行判断(ASCAII最大值是128)
        // 创建一个和ASCAII一样长的数组,并且赋值都是-1
        int[] last = new int[128];
        for (int i = 0; i < 128; i++) {
            last[i] = -1;
        }
        // 获取字符串的长度
        int n = s.length();
        // 不重复字符串长度
        int res = 0;
        // 开始位置下标
        int start = 0;
        for (int i = 0; i < n; i++) {
            // 获取当前字符的ASCAII的码
            int index = s.charAt(i);
            // 比较大小并取大的数值
            start = Math.max(start, last[index] + 1);
            res = Math.max(res, i - start + 1);
            // 将ASCAII数组中对应的下标的值改为i
            last[index] = i;
            // 解释上面三行代码, 如果传入的是"abcad"
            //             i(循环次数)   start(起始位置)   res(长度)   index(ASCAII对应值)
            //第一次循环(a)      0               0            1             -1->0
            //第二次循环(b)      1               0            2             -1->1
            //第三次循环(c)      2               0            3             -1->2
            //第四次循环(a)      3               1            3              0->3
            //第五次循环(d)      4               1            4             -1->4
        }
        return res;
    }
}
